/*
  Program: Mine Mayhem
  File:    options.cc
  Date:    July, 1996 to February,   1997,    version 1.00
	   26 October to 3 December,	      version 2.00
	   8 December to 4 January,  2001,    version 2.10
	   15 January,			      version 2.11
	   18 September to 16 December, 2006, version 2.90

  The configuration dialog box.

  Freeware, Copyright 2006 Jason Hood.
*/

#include "options.h"
#include "minefld.h"
#include "timesicn.h"

enum
{
  ID_START_0 = 1000,
  ID_START_1,
  ID_START_2,
  ID_START_3,

  ID_CHECK_FINOPEN,
  ID_CHECK_FINMARK,

  ID_COUNTER_0,
  ID_COUNTER_1,
  ID_COUNTER_2,

  ID_CHECK_LOGICAL,
  ID_CHECK_MARKS,
  ID_CHECK_WRAP,
  ID_CHECK_TRACK,

  ID_CHECK_AUTOMARK,
  ID_CHECK_AUTOOPEN,
  ID_CHECK_AUTOCLEAR,
};

DEFINE_RESPONSE_TABLE(OptionDlg, TabWin)
  E_BUTTONUP(ID_OK, cmOK)
  E_BUTTONUP(ID_CANCEL, cmCancel)

  E_RADIO_GROUP( ID_START_0, ID_START_3, cmStart)
  E_RADIO_GROUP( ID_COUNTER_0, ID_COUNTER_2, cmCounter)
  E_BOXCHECKED(  ID_CHECK_FINOPEN,   cmFinish)
  E_BOXCHECKED(  ID_CHECK_FINMARK,   cmFinish)
  E_BOXCHECKED(  ID_CHECK_MARKS,     cmGeneral)
  E_BOXCHECKED(  ID_CHECK_TRACK,     cmGeneral)
  E_BOXCHECKED(  ID_CHECK_WRAP,      cmWrap)
  E_BOXCHECKED(  ID_CHECK_AUTOCLEAR, cmClear)
  E_BOXUNCHECKED(ID_CHECK_FINOPEN,   cmFinish)
  E_BOXUNCHECKED(ID_CHECK_FINMARK,   cmFinish)
  E_BOXUNCHECKED(ID_CHECK_MARKS,     cmGeneral)
  E_BOXUNCHECKED(ID_CHECK_TRACK,     cmGeneral)
  E_BOXUNCHECKED(ID_CHECK_WRAP,      cmWrap)
  E_BOXUNCHECKED(ID_CHECK_AUTOCLEAR, cmClear)
END_RESPONSE_TABLE

#define DLG_WIDTH  (SysFont->width*48)
#define DLG_HEIGHT (SysFont->height*20)

OptionDlg::OptionDlg() :
  TabWin(NULL, "Options",
         (ws.GetDeskWidth()-DLG_WIDTH-FWIDTH*2)/2,
         (ws.GetDeskHeight()-DLG_HEIGHT-FWIDTH-CAPTION_HEIGHT)/2,
         (ws.GetDeskWidth()+DLG_WIDTH+FWIDTH*2)/2-1,
         (ws.GetDeskHeight()+DLG_HEIGHT+FWIDTH+CAPTION_HEIGHT)/2,
         WA_VISABLE | WA_BORDER | WA_CAPTION | WA_SAVEAREA),
  isOK(false)
{
  int ox, oy, oy1,
      wid = 20*SysFont->width+8,
      hyt = 6 + 4*(SysFont->height+1);

  ox = FWIDTH+10; oy = FWIDTH+CAPTION_HEIGHT+8+SysFont->height+2;
  start = new RadioGroup(this, ox, oy, ox+wid-1, oy+hyt-1, RADIO_TYPE_DIP);
  start->AddButton("&None",      ID_START_0 + NONE);
  start->AddButton("&Displace",  ID_START_0 + DISPLACE);
  start->AddButton("&Blank",     ID_START_0 + BLANK);
  start->AddButton("&Perimeter", ID_START_0 + PERIMETER);
  start->SelectButton(ID_START_0 + Start);

  wid -= 20;
  ox += 4;
  oy1 = oy += hyt+SysFont->height*2+2+3;
  finishopen = new CheckBox(this, ID_CHECK_FINOPEN, "&Opened", ox, oy, wid,
                            (Finish & ALL_OPENED) != 0);
  oy += SysFont->height+1;
  finishmark = new CheckBox(this, ID_CHECK_FINMARK, "&Marked", ox, oy, wid,
                            (Finish & ALL_MARKED) != 0);

  wid += 20;
  hyt -= SysFont->height+1;
  ox -= 4;
  oy += SysFont->height+3+SysFont->height+SysFont->height+2;
  count = new RadioGroup(this, ox, oy, ox+wid-1, oy+hyt-1, RADIO_TYPE_DIP);
  count->AddButton("Norma&l", ID_COUNTER_0 + NORMAL);
  count->AddButton("&Remove", ID_COUNTER_0 + REMOVE);
  count->AddButton("&Update", ID_COUNTER_0 + UPDATE);
  count->SelectButton(ID_COUNTER_0 + Counter);

  ox = DLG_WIDTH - FWIDTH-6 - wid + 4;
  oy = FWIDTH+CAPTION_HEIGHT+8+SysFont->height+2+3;
  wid -= 20;
  hyt += SysFont->height+1;
  logical = new CheckBox(this, ID_CHECK_LOGICAL,"&Logical",ox,oy,wid,isLogical);
  oy += SysFont->height+1;
  marks = new CheckBox(this, ID_CHECK_MARKS,"M&arks counter",ox,oy,wid,isMarks);
  oy += SysFont->height+1;
  track = new CheckBox(this, ID_CHECK_TRACK, "&Tracking", ox,oy,wid, isTracked);
  oy += SysFont->height+1;
  wrap = new CheckBox(this, ID_CHECK_WRAP, "&Wrap-around", ox, oy, wid, isWrap);

  oy = oy1;
  autoclear = new CheckBox(this, ID_CHECK_AUTOCLEAR, "Cl&earing",
			   ox, oy, wid, isAutoClear);
  oy += SysFont->height+1;
  automark = new CheckBox(this, ID_CHECK_AUTOMARK, "Markin&g",
                          ox, oy, wid, isAutoMark);
  oy += SysFont->height+1;
  autoopen = new CheckBox(this, ID_CHECK_AUTOOPEN, "O&pening",
                          ox, oy, wid, isAutoOpen);

  ix = ox + 2;
  iy = oy + 4*(SysFont->height+1);

  int bwid = 10*SysFont->width, bhyt = SysFontBold->height+4;
  ox = DLG_WIDTH - FWIDTH-6 - (wid+20);
  oy = cy2 - 10 - bhyt;
  Cancel = new TextButton(this, ID_CANCEL, ox, oy,
			  ox+bwid-1, oy+bhyt-1, "&Cancel");
  ox -= bwid + 12;
  OK = new TextButton(this, ID_OK, ox, oy, ox+bwid-1, oy+bhyt-1, "O&K");

  AddTabStop(start);
  AddTabStop(finishopen);
  AddTabStop(finishmark);
  AddTabStop(logical);
  AddTabStop(marks);
  AddTabStop(wrap);
  AddTabStop(track);
  AddTabStop(automark);
  AddTabStop(autoopen);
  AddTabStop(autoclear);
  AddTabStop(count);
  AddTabStop(OK);
  AddTabStop(Cancel);
}


OptionDlg::~OptionDlg()
{
  delete OK; delete Cancel;
  delete autoopen; delete automark; delete autoclear;
  delete wrap; delete track; delete marks; delete logical;
  delete count;
  delete finishmark; delete finishopen;
  delete start;
}

extern BYTE HighLightColour;

// Write all the headings and draw the boxes around the options.
void OptionDlg::PaintWindow(int x1, int y1, int x2, int y2)
{
  TabWin::PaintWindow(x1, y1, x2, y2);

  ViewBuffer* buf = GetSubBuffer(x1, y1, x2, y2);

  int ox = FWIDTH+10, oy = FWIDTH+CAPTION_HEIGHT+8,
      wid = 20*SysFont->width+8,
      hyt = 3 + 4*(SysFont->height+1) + 3;

  WriteText(buf, ox,oy, HighLightColour, SysFontItallic, "Starting Condition");
  oy += SysFont->height+2 + hyt + SysFont->height;
  WriteText(buf, ox,oy, HighLightColour, SysFontItallic, "Finishing Condition");

  oy += SysFont->height+2;
  hyt -= 2*(SysFont->height+1);
  InvFrame(buf, ox, oy, ox+wid-1, oy+hyt-1);
     Frame(buf, ox+1, oy+1, ox+wid-2, oy+hyt-2);

  oy += hyt + SysFont->height;
  WriteText(buf, ox,oy, HighLightColour, SysFontItallic, "Mine Counter");

  ox = DLG_WIDTH - (wid+6+FWIDTH); oy = FWIDTH+CAPTION_HEIGHT+8;
  WriteText(buf, ox, oy, HighLightColour, SysFontItallic, "General");
  oy += SysFont->height+2;
  hyt += 2*(SysFont->height+1);
  InvFrame(buf, ox, oy, ox+wid-1, oy+hyt-1);
     Frame(buf, ox+1, oy+1, ox+wid-2, oy+hyt-2);

  oy += hyt + SysFont->height;
  WriteText(buf, ox,oy, HighLightColour, SysFontItallic, "Automatic");
  oy += SysFont->height+2;
  hyt -= SysFont->height+1;
  InvFrame(buf, ox, oy, ox+wid-1, oy+hyt-1);
     Frame(buf, ox+1, oy+1, ox+wid-2, oy+hyt-2);

  oy += hyt + SysFont->height;
  WriteText(buf, ox,oy, HighLightColour, SysFontItallic, "Times Icon Legend");
  oy += SysFont->height+2;
  hyt -= SysFont->height+2;
  InvFrame(buf, ox, oy, ox+wid-1, oy+hyt-1);
     Frame(buf, ox+1, oy+1, ox+wid-2, oy+hyt-2);
  cmFinish(); cmGeneral(); cmClear();

  DeleteBuffer(buf);
}


void OptionDlg::Run()
{
  Paint();
  RefreshWindow();
  SetFocus(OK);
  CatchMouse();
  CatchKeys();
  ws.RunEvents();
  ws.ResetEvents();
  ReleaseMouse();
  ReleaseKeys();
  if (isOK && field->GameProgress() != PLAYING)
  {
    Start	= start->GetSelectedButton() - ID_START_0;
    Finish	= finishopen->isChecked() | (finishmark->isChecked() << 1);
    Counter	= count->GetSelectedButton() - ID_COUNTER_0;
    isLogical	= logical->isChecked();
    isMarks	= marks->isChecked();
    isTracked	= track->isChecked();
    isWrap	= wrap->isChecked();
    isAutoClear = autoclear->isChecked();
    isAutoMark	= automark->isChecked();
    isAutoOpen	= autoopen->isChecked();
    field->AdjustWrap();		// Make sure the edges are right
  }
}

void OptionDlg::cmOK()
{
  isOK = true;
  ws.StopRunningEvents();
}

void OptionDlg::cmCancel()
{
  isOK = false;
  ws.StopRunningEvents();
}


#define IX(o)	   ix+(o)*(TIMESICONW+4)
#define IC	   0, 0, TIMESICONW-1, TIMESICONH-1
#define ICON(o, i) BitBlt(wnd, IX(o), iy, TimesIcon##i, IC)
#define DISP(o)    RefreshWindow(absx+IX(o), absy+iy, \
				 absx+IX(o)+TIMESICONW, absy+iy+TIMESICONH)

void OptionDlg::cmStart(int ID)
{
  if (ID - ID_START_0 == PERIMETER)
    Box(wnd, ix, iy, ix+TIMESICONW-1, iy+TIMESICONH-1, 14);
  else
  {
    ICON(0, Start[ID - ID_START_0]);
    if (wrap->isChecked())
      BitBltTransparent(wnd, IX(0), iy, TimesIconWrap, IC);
  }
  DISP(0);
}

void OptionDlg::cmFinish()
{
  ICON(1, Finish[finishopen->isChecked() | (finishmark->isChecked() << 1)]);
  DISP(1);
}

void OptionDlg::cmCounter(int ID)
{
  ICON(2, Counter[ID - ID_COUNTER_0]);
  DISP(2);
}

void OptionDlg::cmGeneral()
{
  ICON(3, General[marks->isChecked()][track->isChecked()]);
  DISP(3);
}

void OptionDlg::cmClear()
{
  ICON(4, Clear[autoclear->isChecked()]);
  DISP(4);
}

void OptionDlg::cmWrap()
{
  cmStart(start->GetSelectedButton());
}
